package de.stefanocke.roo.wicket.base;

import java.util.ArrayList;
import java.util.List;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.springframework.roo.classpath.details.annotations.populator.AbstractAnnotationValues;

import de.stefanocke.roo.wicket.model.BeanPropertyMetadataWithDetails;
import de.stefanocke.roo.wicket.model.IBeanPropertiesMetadataProvider;
import de.stefanocke.roo.wicket.model.BeanPropertyMetadata;
import de.stefanocke.roo.wicket.model.JavaTypeMetadataDetails;

@Component(componentAbstract = true)
public abstract class BeanPropertiesAwareMetadataProvider<M extends ItdMetadata, AV extends AbstractAnnotationValues>
		extends ModelClassAwareItdMetadataProviderBase<M, AV> {

	@Reference
	protected IBeanPropertiesMetadataProvider modelClassPropertiesMetadataProvider;

	public BeanPropertiesAwareMetadataProvider(Class<?> triggerClass, Class<M> metadataClass,
			Class<AV> annotationValuesClass, Class<?> kind) {
		super(triggerClass, metadataClass, annotationValuesClass, kind);
	}

	public BeanPropertiesAwareMetadataProvider(Class<?> triggerClass, Class<M> metadataClass, Class<AV> annotationValuesClass) {
		super(triggerClass, metadataClass, annotationValuesClass);
	}

	// @Deprecated
	// public ModelClassPropertiesAwareMetadataProvider(Class<?> triggerClass,
	// Class<M> metadataClass) {
	// super(triggerClass, metadataClass);
	// }

	protected List<BeanPropertyMetadata> getBeanPropertiesMetadata(ModelClassAwareMetadataCreationParams<AV> cmcp) {
		return getBeanPropertiesMetadata(cmcp, false);
	}

	protected List<BeanPropertyMetadata> getBeanPropertiesMetadata(ModelClassAwareMetadataCreationParams<AV> cmcp,
			boolean withExcludedFields) {
		List<BeanPropertyMetadata> beanPropertiesMetadata = modelClassPropertiesMetadataProvider.getBeanPropertiesForModelClass(
				cmcp.getModelClass(), cmcp.getBeanPropertiesClass(), cmcp.getMid(), withExcludedFields);

		return beanPropertiesMetadata;
	}

	protected <C extends ComponentMetadata> List<BeanPropertyMetadataWithDetails<C>> createBeanPropertyMetadataWithDetails(String mid, List<BeanPropertyMetadata> propertyMetadata,
			Class<C> componentMetadataClass) {
			
				List<BeanPropertyMetadataWithDetails<C>> result = new ArrayList<BeanPropertyMetadataWithDetails<C>>(
						propertyMetadata.size());
				for (BeanPropertyMetadata pm : propertyMetadata) {
					JavaTypeMetadataDetails typeDetails = modelClassService.getJavaTypeMetadataDetails(mid, pm.getType());
					BeanPropertyMetadataWithDetails<C> pmwd = new BeanPropertyMetadataWithDetails<C>(pm, typeDetails);
			
					if (!pm.getType().isCoreType() && componentMetadataClass != null) {
						C cm = findWicketMetadata(mid, pm.getType(), componentMetadataClass, null,
								ComponentFilter.<C> filter(mid, pm), false);
						pmwd.setComponentMetadata(cm);
					}
			
					result.add(pmwd);
				}
				return result;
			}

}
